package com.je.gateway.router.loader;

import com.google.common.base.Strings;
import com.je.gateway.router.GlobalRouterParams;
import com.je.gateway.router.model.paramRouter.ParamRouter;
import com.je.gateway.router.model.paramRouter.ParamUrl;
import com.je.gateway.router.model.paramValue.ConfigParamValues;
import com.je.gateway.xml.AbstractXmlConfigResourceLoader;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class UrlParamRouterResourceLoader extends AbstractXmlConfigResourceLoader<ParamRouter> {

    private static final Logger logger = LoggerFactory.getLogger(UrlParamRouterResourceLoader.class);

    private static final String DEFAULT_CONFIG_PAHT = "paramRouter.xml";

    /**
     * pattern属性标签
     */
    private static final String ROUTER_PATTERN_ATTRIBUTE_KEY = "pattern";
    /**
     * enable属性标签
     */
    private static final String ROUTER_ENABLE_ATTRIBUTE_KEY = "enable";
    /**
     * suffix microServiceName属性
     */
    private static final String ROUTER_PATTERN_PARAMURL_PATH_KEY = "path";
    /**
     * suffix realPath
     */
    private static final String ROUTER_PATTERN_PARAMURL_REALPATH_KEY = "realPath";
    /**
     * suffix valueType
     */
    private static final String ROUTER_PATTERN_PARAMURL_VALUETYPE_KEY = "valueType";
    /**
     * suffix valueKey
     */
    private static final String ROUTER_PATTERN_PARAMURL_VALUEKEY_KEY = "valueKey";
    /**
     * suffix microServiceName属性
     */
    private static final String ROUTER_PATTERN_PARAMURL_PARAMKEY_KEY = "paramKey";
    /**
     * suffix substr属性
     */
    private static final String ROUTER_PATTERN_PARAMURL_SUBSTR_KEY = "substr";
    /**
     * suffix subchar属性
     */
    private static final String ROUTER_PATTERN_PARAMURL_SUBCHAR_KEY = "subChar";
    /**
     * suffix subIndex属性
     */
    private static final String ROUTER_PATTERN_PARAMURL_SUBINDEX_KEY = "subIndex";
    /**
     * suffix microServiceName属性
     */
    private static final String ROUTER_PATTERN_PARAMURL_MICROSERVICENAME_KEY = "microServiceName";
    /**
     * suffix versionRule属性
     */
    private static final String ROUTER_PATTERN_PARAMURL_VERSIONRULE_KEY = "versionRule";
    /**
     * suffix prefixSegmentCount属性
     */
    private static final String ROUTER_PATTERN_PARAMURL_PREFIXSEGEMENTCOUNT_KEY = "prefixSegmentCount";

    public UrlParamRouterResourceLoader() {
        this(DEFAULT_CONFIG_PAHT);
    }

    public UrlParamRouterResourceLoader(String resourcePath) {
        super(resourcePath);
    }

    @Override
    public ParamRouter parse(Element rootElement) {
        //获取pattern配置
        String pattern = rootElement.attributeValue(ROUTER_PATTERN_ATTRIBUTE_KEY);
        String enable = rootElement.attributeValue(ROUTER_ENABLE_ATTRIBUTE_KEY);
        ParamRouter paramRouter;
        if(Strings.isNullOrEmpty(pattern)){
            paramRouter = new ParamRouter();
        }else{
            paramRouter = new ParamRouter(pattern);
        }

        if(!Strings.isNullOrEmpty(enable)){
            if("true".equals(enable)){
                paramRouter.setEnable(true);
            }else{
                paramRouter.setEnable(false);
            }
        }

        List<Element> elements = rootElement.elements();
        if(elements == null || elements.isEmpty()){
            return paramRouter;
        }

        for (Element eachElement: elements) {
            paramRouter.addUrl(parseParamUrl(eachElement));
        }
        return paramRouter;
    }

    private ParamUrl parseParamUrl(Element paramUrlElement){
        ParamUrl paramUrl = new ParamUrl();
        String path = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_PATH_KEY);
        String realPath = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_REALPATH_KEY);
        String valueType = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_VALUETYPE_KEY);
        String valueKey = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_VALUEKEY_KEY);
        String paramKey = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_PARAMKEY_KEY);
        String substr = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_SUBSTR_KEY);
        String subChar = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_SUBCHAR_KEY);
        String subIndex = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_SUBINDEX_KEY);
        String microServiceName = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_MICROSERVICENAME_KEY);
        String versionRule = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_VERSIONRULE_KEY);
        String prefixSegementCount = paramUrlElement.attributeValue(ROUTER_PATTERN_PARAMURL_PREFIXSEGEMENTCOUNT_KEY);
        if(Strings.isNullOrEmpty(path) || Strings.isNullOrEmpty(microServiceName) || Strings.isNullOrEmpty(paramKey)
                || Strings.isNullOrEmpty(versionRule) || Strings.isNullOrEmpty(prefixSegementCount)){
            logger.error("Parse xml configuration paramRouter.xml error!");
            System.exit(0);
        }
        paramUrl.setPath(path);
        paramUrl.setRealPath(realPath);
        if(!Strings.isNullOrEmpty(valueType)){
            paramUrl.setValueType(valueType);
        }
        if(!Strings.isNullOrEmpty(substr)){
            paramUrl.setSubstr("1".equals(substr) || "true".equals(substr));
            paramUrl.setSubChar(subChar);
            paramUrl.setSubIndex(Strings.isNullOrEmpty(subIndex)?0:Integer.valueOf(subIndex));
        }
        paramUrl.setValueKey(valueKey);
        if(!valueType.equals(ParamUrl.VALUE_TYPE_STRING) && !valueType.equals(ParamUrl.VALUE_TYPE_ARRAY)){
            throw new RuntimeException(String.format("非法的配置参数，valueType:%s",valueType));
        }

        paramUrl.setParamKey(paramKey);
        paramUrl.setMicroServiceName(microServiceName);
        paramUrl.setVersionRule(versionRule);
        paramUrl.setPrefixSegmentCount(Integer.valueOf(prefixSegementCount));

        List<Element> elements = paramUrlElement.elements();
        for (Element eachValueElement: elements) {
            if(!Strings.isNullOrEmpty(eachValueElement.getStringValue())){
                paramUrl.addParamValue(eachValueElement.getStringValue());
            }
        }

        Element paramRefElement = paramUrlElement.element("paramRef");
        if(paramRefElement == null){
            return paramUrl;
        }
        paramUrl.setParamRef(true);
        ConfigParamValues configParamValues = GlobalRouterParams.GLOBAL_CONFIG_PARAM_VALUES.get(paramKey + "_" + microServiceName);
        if(configParamValues == null || configParamValues.getValues().isEmpty()){
            return paramUrl;
        }
        for (String eachValue : configParamValues.getValues()) {
            paramUrl.addParamValue(eachValue);
        }

        return paramUrl;
    }


}
